/*
 * Indexer.java
 *
 * Created on 6 March 2006, 13:05
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */


import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

import org.apache.lucene.document.Field;
import org.apache.lucene.document.Document;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.core.StopAnalyzer;
import org.apache.lucene.analysis.core.WhitespaceAnalyzer;
import org.apache.lucene.analysis.standard.ClassicAnalyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.search.similarities.AfterEffect;
import org.apache.lucene.search.similarities.AfterEffectB;
import org.apache.lucene.search.similarities.BM25Similarity;
import org.apache.lucene.search.similarities.BasicModel;
import org.apache.lucene.search.similarities.BasicModelBE;
import org.apache.lucene.search.similarities.DFRSimilarity;
import org.apache.lucene.search.similarities.DefaultSimilarity;
import org.apache.lucene.search.similarities.Distribution;
import org.apache.lucene.search.similarities.DistributionLL;
import org.apache.lucene.search.similarities.IBSimilarity;
import org.apache.lucene.search.similarities.LMDirichletSimilarity;
import org.apache.lucene.search.similarities.Lambda;
import org.apache.lucene.search.similarities.LambdaDF;
import org.apache.lucene.search.similarities.Normalization;
import org.apache.lucene.search.similarities.NormalizationH1;
import org.apache.lucene.search.similarities.Similarity;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;


public class Index {
    
    /** Creates a new instance of Indexer */
    public Index() {
    }
 
    private IndexWriter indexWriter = null;
    
    public IndexWriter getIndexWriter(int weighingSchemeOption, int similarityMeasureOption, boolean create) throws IOException {
        if (create) {
        	
        	Analyzer analyser = null;
        	switch(weighingSchemeOption){
        		case 0: 
        			analyser  = new StandardAnalyzer(Version.LUCENE_CURRENT);
        			break;
        		case 1: 
        			analyser  = new ClassicAnalyzer(Version.LUCENE_CURRENT);
					break;
        		case 2:
        			analyser  = new WhitespaceAnalyzer(Version.LUCENE_CURRENT);
        			break;
        		case 3:
        			analyser  = new StopAnalyzer(Version.LUCENE_CURRENT);
        			break;
				
        	}
            Similarity similarity = null;
        	switch(similarityMeasureOption) {
    		case 0:
    			similarity = new DefaultSimilarity();
    			break;
    		case 1:
    			Distribution d = new DistributionLL();
    			Lambda l = new LambdaDF();
    			Normalization n = new NormalizationH1();
    			similarity = new IBSimilarity(d,l,n);
    			break;
    		case 2:
    			similarity = new BM25Similarity();
    			break;
    		case 3:
    			BasicModel bm = new BasicModelBE();
    			AfterEffect a = new AfterEffectB();
    			Normalization nl = new NormalizationH1();
    			similarity = new DFRSimilarity(bm, a, nl);
    			break;
        	}

        	
    		final File docDir = new File("index-directory");

            if (docDir.exists()) {
                deleteDirectory(docDir);
            }
        	
        	FSDirectory idx = FSDirectory.open(new File("index-directory"));
    		IndexWriterConfig indexWriterConfig = new IndexWriterConfig(
    				Version.LUCENE_CURRENT, analyser);
    		indexWriterConfig.setSimilarity(similarity);
    		 indexWriter = new IndexWriter(idx, indexWriterConfig);
            
        }

        return indexWriter;
   }    
   
    public void closeIndexWriter() throws IOException {
        if (indexWriter != null) {
            indexWriter.close();
        }
   }
    
    public static boolean deleteDirectory(File directory) {
        if(directory.exists()){
            File[] files = directory.listFiles();
            if(null!=files){
                for(int i=0; i<files.length; i++) {
                    if(files[i].isDirectory()) {
                        deleteDirectory(files[i]);
                    }
                    else {
                        files[i].delete();
                    }
                }
            }
        }
        return(directory.delete());
    }
    
    public void buildIndexes(int option1,int option2, String folder) throws IOException {
          //
          // Erase existing index
          //
          getIndexWriter(option1, option2,true);

          performIndex(folder);
          

          closeIndexWriter();
     }    
    
    
    public void performIndex(String path){
		File docDir = new File(path);
        File[] files = docDir.listFiles();
        if(null!=files){
            for(int i=0; i<files.length; i++) {
               System.out.println("indexing "+files[i].getName());
            	try {
					BufferedReader br = new BufferedReader(new FileReader(files[i]));
					StringBuilder sb = new StringBuilder();
					String line = br.readLine();
					while (line != null){
						String trim = line.replaceAll("\\s+","");
						String regex = "[0-9]+";
						if (trim.matches(regex)) {
							break;
						}
						sb.append(line);
						sb.append('\n');
						line = br.readLine();
						
					}
					String content = sb.toString();
					System.out.println(content);
					indexFile(content, files[i].getName().replaceFirst("[.][^.]+$", ""));
				} catch (FileNotFoundException e) {
					e.printStackTrace();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
            }
        }
        
    }
  
    private void indexFile(String content, String fileName){
        Document doc = new Document();
        doc.add(new Field("name", fileName, Field.Store.YES, Field.Index.NOT_ANALYZED, Field.TermVector.NO));
        doc.add(new Field("content", content, Field.Store.YES, Field.Index.ANALYZED,Field.TermVector.YES));
        try {
			indexWriter.addDocument(doc);
		} catch (IOException e) {
			e.printStackTrace();
		}
    }
    
    
}
